MODULE_NAME='Paragon - Global Audio Share Source'
(
    Dev vdvInterRoomComms,
    Dev vdvGlobalComms,
    Dev daAllRooms[],
    Dev daAllTPs[],
    Integer nGroupSelectButtons[],
    Integer nZoneSelectButtons[],
    Integer nSelectedZoneOffButton,
    Integer nVolumeUpButton,
    Integer nVolumeDownButton,
    Integer nDisableConnectChan,
    Integer nGlobalListPort,
    Integer nGlobalListAddress,
    Integer nGlobalListViewAddress
)
(***********************************************************)
(***********************************************************)
(*  FILE_LAST_MODIFIED_ON: 04/04/2006  AT: 11:33:16        *)
(***********************************************************)
(* System Type : NetLinx                                   *)
(***********************************************************)
(* REV HISTORY:                                            *)
(***********************************************************)
(*
    $History: $
*)    
#DEFINE DEBUG   
(***********************************************************)
(*          DEVICE NUMBER DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_DEVICE

(***********************************************************)
(*               CONSTANT DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_CONSTANT
cnMaxDebugLen = 200;

cnMaxTPs = 24;
cnMaxZones = 21;
cnMaxGroups = 5;
cnMaxSources = 23;

(***********************************************************)
(*              DATA TYPE DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_TYPE

Structure _sZoneLists
{
    Integer nListLength
    Char  strZoneName[cnMaxZones][35]
    Char  strSourceName[cnMaxZones][35]
    Integer nZoneNumber[cnMaxZones]
    Integer nZoneSource[cnMaxZones]
    Integer nVolume[cnMaxZones]
}

Structure _sAllTPs
{
    Integer nCurrentZone
    Integer nSelectedGroup
    Integer nSelectedRoom
    Integer nCurrentSource
}

(***********************************************************)
(*               VARIABLE DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_VARIABLE
Volatile _sZoneLists sZoneLists[cnMaxGroups]
Volatile _sAllTPs sAllTPs[cnMaxTPs]
Volatile Char strSourceName[cnMaxSources][35]

(***********************************************************)
(*               LATCHING DEFINITIONS GO BELOW             *)
(***********************************************************)
DEFINE_LATCHING

(***********************************************************)
(*       MUTUALLY EXCLUSIVE DEFINITIONS GO BELOW           *)
(***********************************************************)
DEFINE_MUTUALLY_EXCLUSIVE

(***********************************************************)
(*        SUBROUTINE/FUNCTION DEFINITIONS GO BELOW         *)
(***********************************************************)
(* EXAMPLE: DEFINE_FUNCTION <RETURN_TYPE> <NAME> (<PARAMETERS>) *)
(* EXAMPLE: DEFINE_CALL '<NAME>' (<PARAMETERS>) *)

Define_Call 'DEBUG_OUTPUT' (Integer nLine, Char strData[])
{
	#IF_DEFINED DEBUG
	Char strTempData[200];
	Integer nLen;
	
	nLen = Length_String(strData)
	If (nLen < cnMaxDebugLen)
	{
		Send_String 0,"__FILE__,' Line:',Itoa(nLine),' ',strData";
	}
	Else
	{
		strTempData = Left_String(strData,cnMaxDebugLen);
		strData = Right_String(strData,nLen-cnMaxDebugLen);
		Send_String 0,"__FILE__,' Line:',Itoa(nLine),' ',strTempData";
		Send_String 0,"'Continued: ',strData";
	}
	#END_IF
}

Define_Call 'DISPLAY_ROOM_LIST' (Integer nTpIdx)
{
    Stack_Var Integer nI, nJ
    Stack_Var strTempVol[7]
    
    If (sAllTPs[nTpIdx].nSelectedGroup > 0 && sAllTPs[nTpIdx].nSelectedGroup <= cnMaxGroups)
    {
	Call 'DEBUG_OUTPUT' (__LINE__,"'sAllTPs[',Itoa(nTpIdx),'].nSelectedGroup:',Itoa(sAllTPs[nTpIdx].nSelectedGroup)")
	Send_Command daAllTPs[nTpIdx], "'^LDD-',Itoa(nGlobalListAddress)" // Deletes any existing data list
	Send_Command daAllTPs[nTpIdx], "'^LDN-',Itoa(nGlobalListPort),',',Itoa(nGlobalListAddress),',3,Share ',sZoneLists[sAllTPs[nTpIdx].nSelectedGroup].strSourceName[nTpIdx]" //,strCurrentSource"  // Creates new 5-column data list  
	Send_Command daAllTPs[nTpIdx], "'^LDT-',Itoa(nGlobalListAddress),',1,0,0,3'"  // Starting Column, Room Number, Room Name - Room Source Room Volume, Port-Channel
	
	For (nI = 1; nI <= sZoneLists[sAllTPs[nTpIdx].nSelectedGroup].nListLength; nI++)
	{
	    If (sZoneLists[sAllTPs[nTpIdx].nSelectedGroup].nZoneNumber[nI] != sAllTPs[nTPidx].nCurrentZone)
	    {
		If (sZoneLists[sAllTPs[nTpIdx].nSelectedGroup].strSourceName[nI] == 'Off')
		{
		    strTempVol = ''
		}
		Else If (sZoneLists[sAllTPs[nTpIdx].nSelectedGroup].nVolume[nI] == 999)
		{
		    strTempVol = ' - NA'
		}
		Else
		{
		    strTempVol = "' - ',Itoa(sZoneLists[sAllTPs[nTpIdx].nSelectedGroup].nVolume[nI]),'%'"
		}
		Send_Command daAllTPs[nTpIdx], "'^LDA-',Itoa(nGlobalListAddress),',0,',Itoa(sZoneLists[sAllTPs[nTpIdx].nSelectedGroup].nZoneNumber[nI]),',',sZoneLists[sAllTPs[nTpIdx].nSelectedGroup].strZoneName[nI],' - ',sZoneLists[sAllTPs[nTpIdx].nSelectedGroup].strSourceName[nI],strTempVol,',"',Itoa(nGlobalListPort),',',Itoa(nZoneSelectButtons[nI]),'"'"
		If (sAllTPs[nTPidx].nSelectedRoom = sZoneLists[sAllTPs[nTpIdx].nSelectedGroup].nZoneNumber[nI])
		{
		    On[daAllTPs[nTPIdx],nZoneSelectButtons[nI]]
		    Send_Command daAllTPs[nTpIdx], "'@PPN-AUDIO GLOBAL Selected Room'"
		}
		Else
		    Off[daAllTPs[nTPIdx],nZoneSelectButtons[nI]]
	    }
	}
    }
    Send_Command daAllTPs[nTpIdx], "'^LVL-',Itoa(nGlobalListViewAddress),',',Itoa(nGlobalListPort),',',Itoa(nGlobalListAddress)" //set the data list displayed.
    Send_Command daAllTPs[nTpIdx], "'^LVC-',Itoa(nGlobalListViewAddress),',2'"  //Sets the column numbers to display in the view
    Send_Command daAllTPs[nTpIdx], "'^LVU-',Itoa(nGlobalListViewAddress)" //Updates the view
}
(***********************************************************)
(*                STARTUP CODE GOES BELOW                  *)
(***********************************************************)
DEFINE_START


(***********************************************************)
(*                THE EVENTS GO BELOW                      *)
(***********************************************************)
DEFINE_EVENT

Data_Event[vdvGlobalComms]
{
    Command:
    {
	Stack_Var Char strTemp[40], strJunk[10]
	Stack_Var Integer nIdx
	
	// Format: GROUP1=nZoneNumber1:strZoneName1,nZoneNumber2,...	
	Call 'DEBUG_OUTPUT' (__LINE__,"'Data.Text=',Data.Text")
	If (Find_String(Data.Text,'GROUP',1))
	{
	    strJunk = Remove_String(Data.Text,'GROUP',1)
	    nIdx = Atoi(Data.Text)
	    If (nIdx)
	    {
		strJunk = Remove_String(Data.Text,'=',1)
		sZoneLists[nIdx].nListLength = 0
		Call 'DEBUG_OUTPUT' (__LINE__,"'Data.Text=',Data.Text")
		While (Find_String(Data.Text,',',1))
		{
		    sZoneLists[nIdx].nListLength++
		    strTemp = Remove_String(Data.Text,',',1)
		    sZoneLists[nIdx].nZoneNumber[sZoneLists[nIdx].nListLength] = Atoi(strTemp)
		    strJunk = Remove_String(strTemp,':',1)
		    sZoneLists[nIdx].strZoneName[sZoneLists[nIdx].nListLength] = Left_String(strTemp,Length_String(strTemp)-1)
		}
		sZoneLists[nIdx].nListLength++
		sZoneLists[nIdx].nZoneNumber[sZoneLists[nIdx].nListLength] = Atoi(Data.Text)
		strJunk = Remove_String(Data.Text,':',1)
		sZoneLists[nIdx].strZoneName[sZoneLists[nIdx].nListLength] = Data.Text
	    }
	}
	// Format: SOURCEnSourceNumber=strSourceName
	Else If (Find_String(Data.Text,'SOURCE',1))
	{
	    strJunk = Remove_String(Data.Text,'SOURCE',1)
	    nIdx = Atoi(Data.Text)
	    If (nIdx)
	    {
		strJunk = Remove_String(Data.Text,'=',1)
		strSourceName[nIdx] = Data.Text
	    }
	}
	Else If (Find_String(Data.Text,'PANEL_ACTIVE',1))
	{
	    strJunk = Remove_String(Data.Text,'PANEL_ACTIVE',1)
	    nIdx = Atoi(Data.Text)
	    If (nIdx)
	    {
		strJunk = Remove_String(Data.Text,'=',1)
		sAllTPs[nIdx].nCurrentZone = Atoi(Data.Text)
		strJunk = Remove_String(Data.Text,',',1)
		sAllTPs[nIdx].nCurrentSource = Atoi(Data.Text)
		
		If (sAllTPs[nIdx].nCurrentZone)
		{
		    If (sAllTPs[nIdx].nSelectedGroup == 0 || sAllTPs[nIdx].nSelectedGroup > cnMaxGroups)
			sAllTPs[nIdx].nSelectedGroup = 1
		    Call 'DISPLAY_ROOM_LIST' (nIdx)
		}
		Else
		{
		    sAllTPs[nIdx].nSelectedRoom = 0
		    Send_Command daAllTPs[nIdx],"'@PPF-AUDIO GLOBAL Selected Room'"
		}
	    }
	}
    }	
}

Data_Event[vdvInterRoomComms]
{
    Command:
    {
	Stack_Var Char strData[200], strJunk[10]
	Local_Var Integer nSource, nRoom, nI, nJ

	// Format: ROOMFB1=nSourceValue
	// Room #: Unique room identifier
	// nSourceValue: Unique source identifier

	strData = Data.Text
	Call 'DEBUG_OUTPUT' (__LINE__,"'Data.Text:',Data.Text");
	If (Find_String(strData,'ROOMFB',1))
	{
	    Cancel_Wait 'AUTO_UPDATE_DISPLAY_WAIT'
	    strJunk = Remove_String(strData,'ROOMFB',1)
	    nRoom = Atoi(strData)
	    strJunk = Remove_String(strData,'=',1)
	    nSource = Atoi(strData)
	    Call 'DEBUG_OUTPUT' (__LINE__,"'nRoom:',Itoa(nRoom),' nSource:',Itoa(nSource)");
	    For (nI = 1; nI <= cnMaxGroups; nI++)
	    {
		For (nJ = 1; nJ <= sZoneLists[nI].nListLength; nJ++)
		{
		    If (sZoneLists[nI].nZoneNumber[nJ] == nRoom)
		    {
			sZOneLists[nI].nZoneSource[nJ] = nSource
			If (nSource > 0 && nSource <= cnMaxSources)
			{
			    If (Length_String(strSourceName[nSource]))
			    {
				sZoneLists[nI].strSourceName[nJ] = strSourceName[nSource]
			    }
			    Else
			    {
				sZoneLists[nI].strSourceName[nJ] = 'Not Shared'
			    }
			}
			Else
			    sZoneLists[nI].strSourceName[nJ] = 'Off'
		    }
		}
	    }
	    Wait 10 'AUTO_UPDATE_DISPLAY_WAIT'
	    {
		For (nI = 1; nI <= cnMaxTPs; nI++)
		{
		    If (sAllTPs[nI].nCurrentZone)
		    {
			Call 'DISPLAY_ROOM_LIST' (nI)
		    }
		}
	    }
	}
    }
}

Button_Event[daAllTPs,nGroupSelectButtons]
{
    Push:
    {
	Stack_Var Integer nTpIdx, nI

	nTpIdx = Get_Last(daAllTPs)
	sAllTPs[nTpIdx].nSelectedGroup = Get_last(nGroupSelectButtons)	
	On[Button.Input]

	If (sAllTPs[nTpIdx].nCurrentZone)
	{
	    sAllTPs[nTPidx].nSelectedRoom = 0
	    Call 'DISPLAY_ROOM_LIST' (nTpIdx)
	}
    }
}

Button_Event[daAllTPs,nZoneSelectButtons]
{
    Push:
    {
	Stack_Var Integer nTpIdx, nBtnIdx

	nTpIdx = Get_Last(daAllTPs)
	nBtnIdx = Get_last(nZoneSelectButtons)

	Call 'DEBUG_OUTPUT' (__LINE__,"Itoa(Button.Input.Device.Number),':',Itoa(Button.Input.Device.Port),':',Itoa(Button.Input.Device.System),''")
	
	If (sAllTPs[nTpIdx].nSelectedGroup > 0 && sAllTPs[nTpIdx].nSelectedGroup <= cnMaxGroups)
	{
	    Set_Pulse_Time(25)
	    Pulse[Button.Input.Device,nDisableConnectChan]
	    Set_Pulse_Time(5)
	}
	
	If (sAllTPs[nTpIdx].nSelectedRoom != sZoneLists[sAllTPs[nTpIdx].nSelectedGroup].nZoneNumber[nBtnIdx])
	{
	    sAllTPs[nTpIdx].nSelectedRoom = sZoneLists[sAllTPs[nTpIdx].nSelectedGroup].nZoneNumber[nBtnIdx]
	    Send_Command vdvInterRoomComms,"'SWITCHROOM',Itoa(sAllTPs[nTpIdx].nSelectedRoom),'=',Itoa(sAllTPs[nTpIdx].nCurrentSource)"
	}
	Else
	{
	    sAllTPs[nTpIdx].nSelectedRoom = 0
	    Send_Command daAllTPs[nTpIdx],"'@PPF-AUDIO GLOBAL Selected Room'"
	    Off[Button.Input]
	}
    }
}

Button_Event[daAllTPs,nSelectedZoneOffButton]
{
    Push:
    {
	Stack_Var Integer nTpIdx, nI

	nTpIdx = Get_Last(daAllTPs)
	If (sAllTPs[nTpIdx].nSelectedRoom > 0)
	{
	    Send_Command vdvInterRoomComms,"'SWITCHROOM',Itoa(sAllTPs[nTpIdx].nSelectedRoom),'=0'"
	    sAllTPs[nTpIdx].nSelectedRoom = 0
	    Send_Command daAllTPs[nTpIdx],"'@PPF-AUDIO GLOBAL Selected Room'"
	    Off[Button.Input]
	}
    }
}

Button_Event[daAllTPs,nVolumeUpButton]
{
    Push:
    {
	Stack_Var Integer nTpIdx, nI

	nTpIdx = Get_Last(daAllTPs)

	If (sAllTPs[nTpIdx].nSelectedRoom > 0)
	{
	    Do_Push_Timed(daAllRooms[sAllTPs[nTpIdx].nSelectedRoom],1,70)
	    Call 'DEBUG_OUTPUT' (__LINE__,"'sAllTPs[',Itoa(nTpIdx),'].nSelectedRoom:',Itoa(sAllTPs[nTpIdx].nSelectedRoom)")
	}
    }
    Release:
    {
	Stack_Var Integer nTpIdx, nI

	nTpIdx = Get_Last(daAllTPs)

	If (sAllTPs[nTpIdx].nSelectedRoom > 0)
	{
	    Do_Release(daAllRooms[sAllTPs[nTpIdx].nSelectedRoom],1)
	    Call 'DEBUG_OUTPUT' (__LINE__,"'sAllTPs[',Itoa(nTpIdx),'].nSelectedRoom:',Itoa(sAllTPs[nTpIdx].nSelectedRoom)")
	}
    }
}

Button_Event[daAllTPs,nVolumeDownButton]
{
    Push:
    {
	Stack_Var Integer nTpIdx, nI

	nTpIdx = Get_Last(daAllTPs)

	If (sAllTPs[nTpIdx].nSelectedRoom > 0)
	{
	    Do_Push_Timed(daAllRooms[sAllTPs[nTpIdx].nSelectedRoom],2,70)
	    Call 'DEBUG_OUTPUT' (__LINE__,"'sAllTPs[',Itoa(nTpIdx),'].nSelectedRoom:',Itoa(sAllTPs[nTpIdx].nSelectedRoom)")
	}
    }
    Release:
    {
	Stack_Var Integer nTpIdx, nI

	nTpIdx = Get_Last(daAllTPs)

	If (sAllTPs[nTpIdx].nSelectedRoom > 0)
	{
	    Do_Release(daAllRooms[sAllTPs[nTpIdx].nSelectedRoom],2)
	    Call 'DEBUG_OUTPUT' (__LINE__,"'sAllTPs[',Itoa(nTpIdx),'].nSelectedRoom:',Itoa(sAllTPs[nTpIdx].nSelectedRoom)")
	}
    }
}

Level_Event[daAllRooms,1]
{
    Stack_Var Integer nRoomIdx, nTP, nI, nJ
    Stack_Var Char strTempVol[7]
    
    nRoomIdx = Get_Last(daAllRooms)
    Call 'DEBUG_OUTPUT' (__LINE__,"'nRoomIdx:',Itoa(nRoomIdx)")
    For (nTP = 1; nTP <= cnMaxTPs; nTP++)
    {
	If (sAllTPs[nTP].nSelectedGroup > 0 && sAllTPs[nTP].nSelectedGroup <= cnMaxGroups)
	{
	    For (nI = 1; nI <= cnMaxGroups; nI++)
	    {
		For (nJ = 1; nJ <= sZoneLists[nI].nListLength; nJ++)
		{
		    If (sZoneLists[nI].nZoneNumber[nJ] == nRoomIdx)
		    {
			sZoneLists[nI].nVolume[nJ] = Level.Value
		    }
		}
	    }
	    For (nI = 1; nI <= sZoneLists[sAllTPs[nTP].nSelectedGroup].nListLength; nI++)
	    {
		If (sAllTPs[nTP].nCurrentZone && nRoomIdx = sZoneLists[sAllTPs[nTP].nSelectedGroup].nZoneNumber[nI])
		{
		    If (sZoneLists[sAllTPs[nTP].nSelectedGroup].strSourceName[nI] == 'Off')
		    {
			strTempVol = ''
		    }
		    Else If (sZoneLists[sAllTPs[nTP].nSelectedGroup].nVolume[nI] == 999)
		    {
			strTempVol = ' - NA'
		    }
		    Else
		    {
			strTempVol = "' - ',Itoa(sZoneLists[sAllTPs[nTP].nSelectedGroup].nVolume[nI]),'%'"
		    }
		    Send_Command daAllTPs[nTP], "'^LDA-',Itoa(nGlobalListAddress),',0,',Itoa(sZoneLists[sAllTPs[nTP].nSelectedGroup].nZoneNumber[nI]),',',sZoneLists[sAllTPs[nTP].nSelectedGroup].strZoneName[nI],' - ',sZoneLists[sAllTPs[nTP].nSelectedGroup].strSourceName[nI],strTempVol,',"',Itoa(nGlobalListPort),',',Itoa(nZoneSelectButtons[nI]),'"'"
		}
	    }
	}
    }
}

(***********************************************************)
(*            THE ACTUAL PROGRAM GOES BELOW                *)
(***********************************************************)
DEFINE_PROGRAM

(***********************************************************)
(*                     END OF PROGRAM                      *)
(*        DO NOT PUT ANY CODE BELOW THIS COMMENT           *)
(***********************************************************)
